/* Original Author:  Dominick O'Dierno
 * Date: 2007   odiernod@gmail.com     --Originally intended for use with DOMercury:  http://www.odierno.com/domercury
 * Description: Manages assigning the proper actions to thier specific IItems.  It is basically a wrapper around a dictionary of lists of IActions
 * 
 * --CHANGELOG--
 * 
 * */

using System;
using System.Collections.Generic;
using System.Text;
using DOMercury.Interfaces;
using DOMercury.Items;

namespace DOMercury.Managers
{
    public class TypeManager
    {
        //Dictionary of all IActions in DOMercury
        private static Dictionary<string, List<IAction>> actionsdict;
        //initialize the Manager
        public static void Load()
        {
            actionsdict = new Dictionary<string, List<IAction>>();
            BuildDictionary();
        }

        //set the list of Actions according to the passed in ItemType
        public static bool ItemActions(string Type, ref List<IAction> actions)
        {
            try
            {
                bool success = true;
                List<IAction> temp;
                //If ItemType is a file extension, add the generic file extension actions
                if (Type.Substring(0, 1) == ".")
                {
                    success = actionsdict.TryGetValue(".*", out temp);
                    //add registry actions
                    if (Type != ".*")
                    {
                        //now add the actions specific to that file extension
                        if (actionsdict.ContainsKey(Type))
                        {
                            List<IAction> temp2;
                            actionsdict.TryGetValue(Type, out temp2);
                            foreach (IAction a in temp2)
                            {
                                if (!temp.Exists(delegate(IAction ap) { return ap.ActionType == a.ActionType; }))
                                {
                                    temp.Add(a);
                                }
                            }
                        }
                    }
                }
                else
                {
                    success = actionsdict.TryGetValue(Type, out temp);
                }
                actions = temp;
                if (IndexManager.IsMainIndex)
                {
                    //Add "Actions for everybody here
                    if (!actions.Exists(delegate(IAction a) { return a.ActionType == "Change Priority"; }))
                    {
                        actions.Add(new Actions.ChangePriorityAction());
                    }
                }
                
                return success;
            }
            catch
            {
                return false;
            }
        }

        //Add IAction lists to the actions dictionary
        private static void BuildDictionary()
        {
            //create an action list for each type and store it in the dictionary
            List<IAction> AliasActionList = new List<IAction>();
            AliasActionList.Add(new Actions.AliasExecuteAction());
            AliasActionList.Add(new Actions.AliasEditAction());
            AliasActionList.Add(new Actions.AliasDeleteAction());
            actionsdict.Add("alias", AliasActionList);

            List<IAction> MCActionList = new List<IAction>();
            MCActionList.Add(new Actions.MyComputerOpenAction());
            MCActionList.Add(new Actions.MyComputerManageAction());
            actionsdict.Add("my computer", MCActionList);

            List<IAction> DActionList = new List<IAction>();
            DActionList.Add(new Actions.ShowDesktopAction());
            DActionList.Add(new Actions.DesktopOpenAction());
            actionsdict.Add("Desktop", DActionList);

            List<IAction> ExActionList = new List<IAction>();
            ExActionList.Add(new Actions.DOMercuryQuitAction());
            actionsdict.Add("Quit DOMercury", ExActionList);

            List<IAction> DOActionList = new List<IAction>();
            DOActionList.Add(new Actions.DOMercuryShowOptionsAction());
            actionsdict.Add("DOMercury Options", DOActionList);

            List<IAction> PathActionList = new List<IAction>();
            PathActionList.Add(new Actions.PathOpenAction());
            PathActionList.Add(new Actions.PathOpenWithAction());
            PathActionList.Add(new Actions.PathExploreFolderAction());
            PathActionList.Add(new Actions.PathCopyToClipboardAction());
            //PathActionList.Add(new Actions.PathSendToAction());
            //PathActionList.Add(new Actions.PathExploreAction());
            PathActionList.Add(new Actions.PathMoveAction());
            PathActionList.Add(new Actions.PathDeleteAction());
            PathActionList.Add(new Actions.PathCopyAction());
            PathActionList.Add(new Actions.PathRenameAction());
            PathActionList.Add(new Actions.DomGrepAction());
            PathActionList.Add(new Actions.ZipAction());
            PathActionList.Add(new Actions.PathCreateAliasAction());
            actionsdict.Add(".*", PathActionList);

            List<IAction> FolderActionList = new List<IAction>();
            FolderActionList.Add(new Actions.FolderExploreAction());
            FolderActionList.Add(new Actions.FolderExploreFolderAction());
            //FolderActionList.Add(new Actions.FolderSendToAction());
            FolderActionList.Add(new Actions.FolderCmdOpenAction());
            FolderActionList.Add(new Actions.PathCopyToClipboardAction());
            FolderActionList.Add(new Actions.FolderMoveAction());
            FolderActionList.Add(new Actions.FolderDeleteAction());
            FolderActionList.Add(new Actions.FolderRenameAction());
            FolderActionList.Add(new Actions.FolderNewFolderAction());
            FolderActionList.Add(new Actions.DomGrepAction());
            FolderActionList.Add(new Actions.ZipAction());
            FolderActionList.Add(new Actions.PathCreateAliasAction());
            actionsdict.Add("folder", FolderActionList);

            List<IAction> TextActionList = new List<IAction>();       
            TextActionList.Add(new Actions.TextExecuteCommandAction());
            TextActionList.Add(new Actions.TextOpenInIEAction());
            TextActionList.Add(new Actions.TextExecuteCommandInShellAction());
            TextActionList.Add(new Actions.AliasAddAction());
            actionsdict.Add("text", TextActionList);

            List<IAction> SWActionList = new List<IAction>();
            SWActionList.Add(new Actions.SWShow());
            SWActionList.Add(new Actions.SWMaximize());
            SWActionList.Add(new Actions.SWMinimize());
            SWActionList.Add(new Actions.SWRestore());
            SWActionList.Add(new Actions.SWClose());
            actionsdict.Add("system window", SWActionList);

            List<IAction> CWActionList = new List<IAction>();
            CWActionList.Add(new Actions.CWMinimize());
            CWActionList.Add(new Actions.CWMaximize());
            CWActionList.Add(new Actions.CWRestore());
            CWActionList.Add(new Actions.CWClose());
            //CWActionList.Add(new Actions.CWClose());
            actionsdict.Add("current window", CWActionList);

            List<IAction> SMActionList = new List<IAction>();
            SMActionList.Add(new Actions.StartMenuLaunchAction());
            SMActionList.Add(new Actions.StartMenuOpenFolderAction());
            actionsdict.Add("start menu item", SMActionList);

            List<IAction> SSCActionList = new List<IAction>();
            SSCActionList.Add(new Actions.StartScreenSaverAction());
            SSCActionList.Add(new Actions.ChangeScreenSaverAction());
            actionsdict.Add("ScreenSaverItem", SSCActionList);

            List<IAction> RIActionList = new List<IAction>();
            RIActionList.Add(new Actions.RefreshIndexAction());
            actionsdict.Add("RefreshIndexItem", RIActionList);

            List<IAction> GoogleActionList = new List<IAction>();
            GoogleActionList.Add(new Actions.GoogleSearchAction());
            GoogleActionList.Add(new Actions.GoogleImageSearchAction());
            GoogleActionList.Add(new Actions.GmailSearchAction());
            GoogleActionList.Add(new Actions.GoogleMapSearchAction());
            GoogleActionList.Add(new Actions.GoogleVideoSearchAction());
            GoogleActionList.Add(new Actions.GoogleProductSearchAction());
            actionsdict.Add("Google Item", GoogleActionList);

            List<IAction> TxtActionList = new List<IAction>();
            TxtActionList.Add(new Actions.TextAppendAction());
            actionsdict.Add(".txt", TxtActionList);
            actionsdict.Add(".log", TxtActionList);
            actionsdict.Add(".csv", TxtActionList);
            ReloadPluginActions();
        }

        /// <summary>
        /// Reload provided actions from plugin ActionProviders
        /// </summary>
        public static void ReloadPluginActions()
        {
            
            List<IAction> PluginActions;
            foreach (IActionProvider p in PluginManager.ActionProviders)
            {
                //If the dictionary contains the ItemType, add the actions to it
                if (actionsdict.ContainsKey(p.ItemType))
                {
                    actionsdict.TryGetValue(p.ItemType, out PluginActions);
                    foreach (IAction ap in p.Actions)
                    {
                        //add the action if it does not already exist
                        if (!PluginActions.Exists(delegate(IAction a) { return a.ActionType == ap.ActionType; }))
                            PluginActions.Add(ap);
                    }

                }
                //If the dictionary does not contain the ItemType, add the ItemType and the action to the dictionary
                else
                {
                    PluginActions = new List<IAction>(p.Actions);

                    actionsdict.Add(p.ItemType, PluginActions);
                }

            }
        }
    }
}
